package com.top.application.utils;

import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * 
 * @ClassName: PemUtils 
 * @Description: TODO(pem文件读取工具类) 
 * @author zhaiey
 * @date 2018年4月9日 上午9:11:25 
 *
 */
public class PemUtils {

	/**
	 * 
	 * @Title: parsePEMFile 
	 * @Description: TODO(传入pem文件对象，解析pem文件，返回pem文件字节数组) 
	 * @param @param pemFile
	 * @param @return
	 * @param @throws IOException    设定文件 
	 * @author zhaiey
	 * @return byte[]    返回类型 
	 * @throws
	 */
    private static byte[] parsePEMFile(File pemFile) throws IOException {
        if (!pemFile.isFile() || !pemFile.exists()) {
            throw new FileNotFoundException(String.format("The file '%s' doesn't exist.", pemFile.getAbsolutePath()));
        }
        PemReader reader = new PemReader(new FileReader(pemFile));
        PemObject pemObject = reader.readPemObject();
        byte[] content = pemObject.getContent();
        reader.close();
        return content;
    }

    /**
     * 
     * @Title: getPublicKey 
     * @Description: TODO(获取公钥) 
     * @param @param keyBytes
     * @param @param algorithm
     * @param @return    设定文件 
     * @author zhaiey
     * @return PublicKey    返回类型 
     * @throws
     */
    private static PublicKey getPublicKey(byte[] keyBytes, String algorithm) {
        PublicKey publicKey = null;
        try {
            KeyFactory kf = KeyFactory.getInstance(algorithm);
            EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            publicKey = kf.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Could not reconstruct the public key, the given algorithm could not be found.");
        } catch (InvalidKeySpecException e) {
            System.out.println("Could not reconstruct the public key");
        }

        return publicKey;
    }

    /**
     * 
     * @Title: getPrivateKey 
     * @Description: TODO(获取私钥) 
     * @param @param keyBytes
     * @param @param algorithm
     * @param @return    设定文件 
     * @author zhaiey
     * @return PrivateKey    返回类型 
     * @throws
     */
    private static PrivateKey getPrivateKey(byte[] keyBytes, String algorithm) {
        PrivateKey privateKey = null;
        try {
            KeyFactory kf = KeyFactory.getInstance(algorithm);
            EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            privateKey = kf.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Could not reconstruct the private key, the given algorithm could not be found.");
        } catch (InvalidKeySpecException e) {
            System.out.println("Could not reconstruct the private key");
        }

        return privateKey;
    }

    /**
     * 
     * @Title: readPublicKeyFromFile 
     * @Description: TODO(从pem文件中读取公钥) 
     * @param @param filepath
     * @param @param algorithm
     * @param @return
     * @param @throws IOException    设定文件 
     * @author zhaiey
     * @return PublicKey    返回类型 
     * @throws
     */
    public static PublicKey readPublicKeyFromFile(String filepath, String algorithm) throws IOException {
        byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
        return PemUtils.getPublicKey(bytes, algorithm);
    }

    /**
     * 
     * @Title: readPrivateKeyFromFile 
     * @Description: TODO(从pem文件中读取私钥) 
     * @param @param filepath
     * @param @param algorithm
     * @param @return
     * @param @throws IOException    设定文件 
     * @author zhaiey
     * @return PrivateKey    返回类型 
     * @throws
     */
    public static PrivateKey readPrivateKeyFromFile(String filepath, String algorithm) throws IOException {
        byte[] bytes = PemUtils.parsePEMFile(new File(filepath));
        return PemUtils.getPrivateKey(bytes, algorithm);
    }

}
